#include "zigbee.h"
#include "DevLog.h"
#include "time.h"
#include "Open.h"
#include "Shake.h"

/*
ZigBee 网络建立

协调器: 
 1. 上电, 建立网络;
 2. 等待设备入网; 获取设备MAC
 3. 通过MAC查找设备短地址;
 4. 通过短地址; 单播通信;
 5. 定时心跳;
终端:
 1. 上电, 重置网络; 重新加入网络;
 2. 设备注册; 上报MAC地址;
 3. 通过短地址; 单播通信;
*/

/**
 * @brief ZigBee 数据缓冲区
 */
bsp_uart_rev_t* ZigBee=NULL;

/**
 * @brief ZigBee 初始化;
 * 1: ZigBee 模组正常;
 * 0: ZigBee 模组损坏;
 */
uint32_t g_ZigBee_Init;

ZigBee_Property_t Zigbee_Property={0};

/**
 * @brief ZigBee 初始化
 * @note 
 *   串口波特率: 115200
 *   串口通信参数: 8N1
 */
void ZigBee_Init(void)
{
    bsp_err_t Err;
    Bsp_Usart_Init();
    ZigBee = &BspUart;

    // 检查 ZigBee 模组是否正常;
    Err = ZigBee_Check(2000);
    if( Err != TRUE ) 
    { 
        printf("Zigbee check is error: %s\n", bsp_err_to_name(Err));
        return ; 
    }

    // 获取设备地址
    Err = ZigBee_Get_Mac_Addr(Zigbee_Property.Mac, 8, 1000);
    if( Err != TRUE ) 
    {
        ZigBee_Get_Mac_Addr(Zigbee_Property.Mac, 8, 1000);
    }

    // 获取设备短地址;
    Err = ZigBee_Get_ShortAddr(&Zigbee_Property.ShortAddr, 1000);
    if( Err != TRUE ) 
    {
        ZigBee_Get_ShortAddr(&Zigbee_Property.ShortAddr, 1000);
    }

#if ZIGBEE_CLIENT_ENABLE
    // 开启ZigBee客户端
    Err = ZigBee_Client_Start();
    if(Err == TRUE)
    {
        printf("Zigbee client start is ok\n");
    }
    else
    {
        printf("Zigbee client start is error: %s\n", bsp_err_to_name(Err));
    }
#endif

#if ZIGBEE_SERVER_ENABLE
    // 开启ZigBee服务端
    Err = ZigBee_Server_Start();
    if(Err == TRUE)
    {
        printf("Zigbee server start is ok\n");
    }
    else
    {
        printf("Zigbee server start is error: %s\n", bsp_err_to_name(Err));
    }
#endif

    Bsp_Usart_RevBuf_Clear();
}

// 打印数据 HEX
static void Print_Buf_Hex(const void * Buf, int Len)
{
	int i=0;
	uint8_t* pData = (uint8_t*)Buf;
	for(i=0; i<Len; i++)
	{
		printf("%02X ", pData[i]);
	}
	if(Len>0) { printf("\n"); }
}

/**
 * @brief ZigBee 发送数据
 * 
 * @param Data 待发送的数据区
 * @param Len 待发送的数据区长度
 */
void ZigBee_Send(const void * Data, uint32_t Len)
{
//    printf("ZigBee Send Data : ");
//    Print_Buf_Hex(Data, Len);
    
    Bsp_Usart_Send(Data, Len);
}

/**
 * @brief ZigBee 等待数据响应
 * 
 * @param TimeToWait 超时时间
 * @return bsp_err_t 
 * @retval
 * 成功: TRUE
 * 失败: FALSE
 */
bsp_err_t ZigBee_WaitAck(uint32_t TimeToWait)
{
    bsp_err_t Err = Bsp_Usart_WaitAck(TimeToWait);
//    printf("ZigBee Recv Data : ");
//    Print_Buf_Hex(ZigBee->Buf, ZigBee->Len);
    return Err;
}

/**
 * @brief 设置设备类型
 * 
 * @param DevType 
 * @param TimeToWait 
 * @return bsp_err_t 
 */
bsp_err_t ZigBee_Set_DevType(ZigBee_DevType_t DevType, uint32_t TimeToWait)
{
    bsp_err_t Err;
    uint8_t Cmd[]={0xFD, 0x02, 0x01, 0x02, 0xFF,};
    
    Cmd[3] = DevType;

    ZigBee_Send(Cmd, sizeof(Cmd));

    Err = ZigBee_WaitAck(TimeToWait);
    if( Err != TRUE ) { return Err; }

    if( (ZigBee->Buf[0]==0xFA) && (ZigBee->Buf[1]==0x01) )
    {
        return TRUE;
    }

    return ERR_ACK;
}


/**
 * @brief 查看当前设备类型
 * 
 * @param DevType 
 * @return bsp_err_t 
 */
bsp_err_t ZigBee_Get_DevType(ZigBee_DevType_t* DevType, uint32_t TimeToWait)
{
    bsp_err_t Err;
    uint8_t Cmd[]={0xFE, 0x01, 0x01, 0xFF,};
    
    ZigBee_Send(Cmd, sizeof(Cmd));

    Err = ZigBee_WaitAck(TimeToWait);
    if( Err != TRUE ) { return Err; }
    
    if(ZigBee->Buf[0] == 0xFB)
    {
        *DevType = (ZigBee_DevType_t)ZigBee->Buf[1];
        return TRUE;
    }

    return ERR_ACK;
}

/**
 * @brief 获取设备网络状态
 * 
 * @param NetState 网络状态缓冲区
 * @param TimeToWait 超时时间
 * @return bsp_err_t 
 */
bsp_err_t ZigBee_Get_NetState(ZigBee_NetState_t* NetState, uint32_t TimeToWait)
{
    bsp_err_t Err;
    uint8_t Cmd[]={0xFE, 0x01, 0x02, 0xFF,};
    
    ZigBee_Send(Cmd, sizeof(Cmd));

    Err = ZigBee_WaitAck(TimeToWait);
    if( Err != TRUE ) { return Err; }
    
    if(ZigBee->Buf[0] == 0xFB)
    {
        *NetState = (ZigBee_NetState_t)ZigBee->Buf[1];
        return TRUE;
    }
    
    return ERR_ACK;
}

/**
 * @brief 设置 Pan_ID
 * 
 * @param Pan_ID : 固定网络: 0~FFFE; 随机网络: FFFF
 * @param TimeToWait 
 * @return bsp_err_t 
 */
bsp_err_t ZigBee_Set_PanID(uint16_t Pan_ID, uint32_t TimeToWait)
{
    bsp_err_t Err;
    uint8_t Cmd[]={0xFD, 0x03, 0x03, 0xff, 0xff, 0xFF,};
    
    Cmd[3] = (Pan_ID>>8)&0xff;
    Cmd[4] = Pan_ID&0xff;

    ZigBee_Send(Cmd, sizeof(Cmd));

    Err = ZigBee_WaitAck(TimeToWait);
    if( Err != TRUE ) { return Err; }

    if( (ZigBee->Buf[0]==0xFA) && (ZigBee->Buf[1]==0x03) )
    {
        return TRUE;
    }

    return ERR_ACK;
}

/**
 * @brief 获取 Pan_ID
 * 
 * @param Pan_ID 
 * @param TimeToWait 
 * @return bsp_err_t 
 */
bsp_err_t ZigBee_Get_PanID(uint16_t* Pan_ID, uint32_t TimeToWait)
{
    bsp_err_t Err;
    uint8_t Cmd[]={0xFE, 0x01, 0x03, 0xFF,};
    
    ZigBee_Send(Cmd, sizeof(Cmd));

    Err = ZigBee_WaitAck(TimeToWait);
    if( Err != TRUE ) { return Err; }
    
    if(ZigBee->Buf[0] == 0xFB)
    {
        *Pan_ID = (ZigBee->Buf[1]<<8) |\
                   ZigBee->Buf[2];
        return TRUE;
    }
    
    return ERR_ACK;
}


/**
 * @brief 获取 ShortAddr
 * 
 * @param ShortAddr 
 * @param TimeToWait 
 * @return bsp_err_t 
 */
bsp_err_t ZigBee_Get_ShortAddr(uint16_t* ShortAddr, uint32_t TimeToWait)
{
    bsp_err_t Err;
    uint8_t Cmd[]={0xFE, 0x01, 0x05, 0xFF,};
    
    ZigBee_Send(Cmd, sizeof(Cmd));

    Err = ZigBee_WaitAck(TimeToWait);
    if( Err != TRUE ) { return Err; }
    
    if(ZigBee->Buf[0] == 0xFB)
    {
        *ShortAddr = (ZigBee->Buf[1]<<8) |\
                      ZigBee->Buf[2];
        return TRUE;
    }
    
    return ERR_ACK;
}

/**
 * @brief 获取 MAC 地址
 * 
 * @param Mac_Addr : 8 Bytes
 * @param Len 
 * @param TimeToWait 
 * @return bsp_err_t 
 */
bsp_err_t ZigBee_Get_Mac_Addr(uint8_t* Mac_Addr, uint8_t Len, uint32_t TimeToWait)
{
    int i=0;
    bsp_err_t Err;
    uint8_t Cmd[]={0xFE, 0x01, 0x06, 0xFF,};
    
    ZigBee_Send(Cmd, sizeof(Cmd));

    Err = ZigBee_WaitAck(TimeToWait);
    if( Err != TRUE ) { return Err; }
    
    if( (ZigBee->Buf[0]==0xFB) && (ZigBee->Len==9) )
    {
        if(Len > 8) { Len=8; }

        for(i=0; i<8; i++)
        {
            memcpy(Mac_Addr, &ZigBee->Buf[1], Len);
        }
        return TRUE;
    }

    return ERR_ACK;
}



/**
 * @brief 获取 父节点 MAC 地址
 * 
 * @param Coor_Mac_Addr : 8 Bytes
 * @param Len 
 * @param TimeToWait 
 * @return bsp_err_t 
 */
bsp_err_t ZigBee_Get_Coor_Mac_Addr(uint8_t* Coor_Mac_Addr, uint8_t Len, uint32_t TimeToWait)
{
    int i=0;
    bsp_err_t Err;
    uint8_t Cmd[]={0xFE, 0x01, 0x05, 0xFF,};
    
    ZigBee_Send(Cmd, sizeof(Cmd));

    Err = ZigBee_WaitAck(TimeToWait);
    if( Err != TRUE ) { return Err; }
    
    if( (ZigBee->Buf[0]==0xFB) && (ZigBee->Len==9) )
    {
        if(Len > 8) { Len=8; }

        for(i=0; i<8; i++)
        {
            memcpy(Coor_Mac_Addr, &ZigBee->Buf[1], Len);
        }
        return TRUE;
    }

    return ERR_ACK;
}

/**
 * @brief 获取网络中任意 MAC 地址的短地址
 * 
 * @param Mac_Addr 
 * @param ShortAddr 
 * @param TimeToWait 
 * @return bsp_err_t 
 */
bsp_err_t ZigBee_Get_Mac_ShortAddr(uint8_t* Mac_Addr, uint8_t Mac_Len, uint16_t* ShortAddr, uint32_t TimeToWait)
{
    bsp_err_t Err;
    uint8_t Cmd[20]={0};
    uint8_t Len=0;

    Cmd[Len++] = 0xFE; Cmd[Len++] = 0x09; Cmd[Len++] = 0x10;
    memcpy(&Cmd[Len], Mac_Addr, Mac_Len); Len+=Mac_Len;
    Cmd[Len++] = 0xFF;
    
    ZigBee_Send(Cmd, Len);

    Err = ZigBee_WaitAck(TimeToWait);
    if( Err != TRUE ) { return Err; }
    
    if(ZigBee->Buf[0] == 0xFB)
    {
        *ShortAddr = (ZigBee->Buf[1]<<8) |\
                      ZigBee->Buf[2];
        return TRUE;
    }

    return ERR_ACK;
}

/**
 * @brief ZigBee 模组重启
 * 
 * @param TimeToWait 
 * @return bsp_err_t 
 */
bsp_err_t ZigBee_Restart(uint32_t TimeToWait)
{
    bsp_err_t Err;
    uint8_t Cmd[]={0xFD, 0x01, 0x12, 0xFF,};
    
    ZigBee_Send(Cmd, sizeof(Cmd));

    Err = ZigBee_WaitAck(TimeToWait);
    if( Err != TRUE ) { return Err; }
    
    if( (ZigBee->Buf[0]==0xFA) && (ZigBee->Buf[1]==0x12) )
    {
        return TRUE;
    }
    
    return ERR_ACK;
}


/**
 * @brief ZigBee 恢复出厂设置
 * 
 * @param TimeToWait : 超时时间 >= 500ms
 * @return bsp_err_t 
 */
bsp_err_t ZigBee_Reset(uint32_t TimeToWait)
{
    bsp_err_t Err;
    uint8_t Cmd[]={0xFD, 0x01, 0x13, 0xFF,};
    
    ZigBee_Send(Cmd, sizeof(Cmd));

    Err = ZigBee_WaitAck(TimeToWait);
    if( Err != TRUE ) { return Err; }
    
    if( (ZigBee->Buf[0]==0xFA) && (ZigBee->Buf[1]==0x13) )
    {
        return TRUE;
    }
    
    return ERR_ACK;
}

/**
 * @brief ZigBee 参数保存
 * 
 * @param Enable : 0: 不保存; 1: 保存;
 * @param TimeToWait : 超时时间 >= 500ms
 * @return bsp_err_t 
 */
bsp_err_t ZigBee_Save_Enable(uint8_t Enable, uint32_t TimeToWait)
{
    bsp_err_t Err;
    
    uint8_t Cmd[]={0xFD, 0x02, 0x30, 0x00, 0xFF,};

    Cmd[3] = Enable;
    
    ZigBee_Send(Cmd, sizeof(Cmd));

    Err = ZigBee_WaitAck(TimeToWait);
    if( Err != TRUE ) { return Err; }
    
    if( (ZigBee->Buf[0]==0xFA) && (ZigBee->Buf[1]==0x30) )
    {
        return TRUE;
    }
    
    return ERR_ACK;
}

/**
 * @brief ZigBee 向网络中 短地址 发送数据; 点播（单播）data
 * 
 * @param ShortAddr 
 * @param Data 
 * @param Len 
 * @return bsp_err_t 
 */
void ZigBee_Send_Data(uint16_t ShortAddr, const void * Data, int Len)
{
    uint8_t SndBuf[128]={0};
    int SndLen=0;

    if(Len>70) { Len=70; }

    // 头部
    SndBuf[SndLen++] = 0xFC;
    // 数据长度
    SndBuf[SndLen++] = 0x00;
    // 点播（单播）data
    SndBuf[SndLen++] = 0x03;
    // 短地址方式（携带信息为短地址）
    SndBuf[SndLen++] = 0x02;
    // 网络短地址
    SndBuf[SndLen++] = (ShortAddr>>8)&0xff;
    SndBuf[SndLen++] = ShortAddr&0xff;
    // 数据
    memcpy(&SndBuf[SndLen], Data, Len); SndLen+=Len;

    SndBuf[1] = SndLen-2;

    ZigBee_Send(SndBuf, SndLen);
}

/**
 * @brief ZigBee 模组测试;
*/
bsp_err_t ZigBee_Check(uint32_t TimeToWait)
{
    ZigBee_NetState_t Tmp;
    bsp_err_t Err;
    uint8_t Count=3;
    do{
        Err = ZigBee_Get_NetState(&Tmp, TimeToWait);
        
        if(Err == TRUE) {return TRUE;}
        delay_ms(500);

    } while (--Count);
	return Err;
}


void ZigBee_Data_Print(ZigBee_Data_t Data)
{
    printf("dev_mac: ");
    Print_Buf_Hex(Data.dev_mac, sizeof(Data.dev_mac));
    printf("is_shake: %d", Data.is_shake);
    printf("is_open:  %d", Data.is_open);
}

/**
 * @brief ZigBee 服务端启动;
*/
bsp_err_t ZigBee_Server_Start(void)
{
    bsp_err_t Err;
    ZigBee_DevType_t DevType;
    uint16_t Pan_ID=0xffff;
    
    Err = ZigBee_Get_DevType(&DevType, 1000);
    if(Err!=TRUE) { return Err; }

    if(DevType == DEV_TYPE_COOR)
    {
        return TRUE;
    }

    ZigBee_Reset(1000);
    
    DevType = DEV_TYPE_COOR;
    Err = ZigBee_Set_DevType(DevType, 1000);
    if(Err!=TRUE) { return Err; }

    Err = ZigBee_Set_PanID(Pan_ID, 1000);
    if(Err!=TRUE) { return Err; }

    Err = ZigBee_Save_Enable(1, 1000);
    if(Err!=TRUE) { return Err; }

	return TRUE;
}


/**
 * @brief ZigBee 服务端启动;
*/
bsp_err_t ZigBee_Client_Start(void)
{
    bsp_err_t Err;
    ZigBee_DevType_t DevType;
    uint16_t Pan_ID=0xffff; Pan_ID=Pan_ID;
    
    Err = ZigBee_Get_DevType(&DevType, 1000);
    if(Err!=TRUE) { return Err; }

    if(DevType == DEV_TYPE_END_DEV)
    {
        return TRUE;
    }

    // DevType = DEV_TYPE_END_DEV;
    // Err = ZigBee_Set_DevType(DevType, 1000);
    // if(Err!=TRUE) { return Err; }

    // Err = ZigBee_Set_PanID(Pan_ID, 1000);
    // if(Err!=TRUE) { return Err; }

    Err = ZigBee_Reset(1000);
    if(Err!=TRUE) { return Err; }

    Err = ZigBee_Save_Enable(1, 1000);
    if(Err!=TRUE) { return Err; }

	return TRUE;
}


/**
 * @brief ZigBee 服务端重置;
*/
bsp_err_t ZigBee_Server_Reset(void)
{
    bsp_err_t Err;
    ZigBee_DevType_t DevType;
    uint16_t Pan_ID=0xffff;
    
    Err = ZigBee_Get_DevType(&DevType, 1000);
    if(Err!=TRUE) { return Err; }

    if(DevType != DEV_TYPE_COOR)
    {
        printf("Device is not zigbee server\n");
        return FALSE;
    }

    ZigBee_Reset(1000);

    DevType = DEV_TYPE_COOR;
    Err = ZigBee_Set_DevType(DevType, 1000);
    if(Err!=TRUE) { return Err; }

    Err = ZigBee_Set_PanID(Pan_ID, 1000);
    if(Err!=TRUE) { return Err; }

    Err = ZigBee_Save_Enable(1, 1000);
    if(Err!=TRUE) { return Err; }

	return TRUE;
}


/**
 * @brief ZigBee 服务端重置;
*/
bsp_err_t ZigBee_Client_Reset(void)
{
    bsp_err_t Err;
    ZigBee_DevType_t DevType;
    uint16_t Pan_ID=0xffff; Pan_ID=Pan_ID;
    
    Err = ZigBee_Get_DevType(&DevType, 1000);
    if(Err!=TRUE) { return Err; }

    if(DevType != DEV_TYPE_END_DEV)
    {
        printf("Device is not zigbee client\n");
        return TRUE;
    }

    // DevType = DEV_TYPE_END_DEV;
    // Err = ZigBee_Set_DevType(DevType, 1000);
    // if(Err!=TRUE) { return Err; }

    // Err = ZigBee_Set_PanID(Pan_ID, 1000);
    // if(Err!=TRUE) { return Err; }

    Err = ZigBee_Reset(1000);
    if(Err!=TRUE) { return Err; }

    Err = ZigBee_Save_Enable(1, 1000);
    if(Err!=TRUE) { return Err; }

	return TRUE;
}

/**
 * @brief ZigBee 服务端数据处理;
 * 接收数据格式: 有效数据 + 设备短地址;
*/
void ZigBee_Server_Data_Handle(void)
{
    if(ZigBee->Flag != 1) { return ; }

    ZigBee_Data_t Client={0};
    ZigBee_Data_Ack_t ServerAck={0};
    Log_Shake_t ShakeLog={0};
    Log_Open_t OpenLog={0};
    uint32_t timeStemp=0;
    uint16_t ShortAddr=0;

    // Lora State
    if(ZigBee->Len == 2) { Bsp_Usart_RevBuf_Clear(); return ; }
    
    if(ZigBee->Len > 5)
    {
        // printf("Zigbee server recv: ");
//        Print_Buf_Hex(ZigBee->Buf, ZigBee->Len);
    }

    if(ZigBee->Len != (sizeof(Client)+2) ) 
    {
        // printf("Zigbee server receive data is error\n");
        Bsp_Usart_RevBuf_Clear();
        return ;
    }

    memcpy(&Client, ZigBee->Buf, sizeof(Client));
    ShortAddr = ZigBee->Buf[sizeof(Client)] << 8|
                ZigBee->Buf[sizeof(Client)+1];

    // ZigBee_Data_Print(Client);
    // printf("dev short addr is %04X(HEX)\n", ShortAddr);

    if(ShortAddr!=0)
    {
        memcpy(ServerAck.dev_mac, Zigbee_Property.Mac, sizeof(Zigbee_Property.Mac));
        timeStemp = time_get();
        
        /**
         * @brief 保存震动记录;
         */
        if(Client.is_shake)
        {
            ShakeLog.ShortAddr = ShortAddr;
            ShakeLog.timeStamp = timeStemp;
            if(DevLog_Shake_Add(ShakeLog) == EF_NO_ERR)
            {
                ServerAck.shake_res = 1;
            }
        }

        /**
         * @brief 保存震动记录;
         */
        if(Client.is_open)
        {
            OpenLog.ShortAddr = ShortAddr;
            OpenLog.timeStamp = timeStemp;
            if(DevLog_Open_Add(OpenLog) == EF_NO_ERR)
            {
                ServerAck.open_res = 1;
            }
        }

        ZigBee_Send_Data(ShortAddr, &ServerAck, sizeof(ServerAck));
    }

    Bsp_Usart_RevBuf_Clear();
}

/**
 * @brief ZigBee 客户端上传震动/开窗记录
 * 
 */
void ZigBee_Client_Upload_Handle(void)
{
    Open_Enable();
    Shake_Enable();

    ZigBee_Data_t Client={0};
    uint16_t Server_ShortAddr=0;

    memcpy(Client.dev_mac, Zigbee_Property.Mac, sizeof(Zigbee_Property.Mac));

    if(Is_Open())
    {
        Open_Disable();
        Client.is_open = 1;
    }

    if(Is_Shake())
    {
        Shake_Disable();
        Client.is_shake = 1;
    }

    if( (Client.is_open==1) || (Client.is_shake==1) )
    {
        ZigBee_Send_Data(Server_ShortAddr, &Client, sizeof(Client));
        delay_ms(1500);
    }

    /**
     * @brief 响应不处理;
     */
    Bsp_Usart_RevBuf_Clear();

    Open_Enable();
    Shake_Enable();
    delay_ms(100);
}   

/**
 * @brief 客户端Ping服务端, 是否接收到服务端的数据;
 * 
 * @param TimeToWait 
 * @return bsp_err_t 
 */
bsp_err_t Client_Ping(uint32_t TimeToWait)
{
    bsp_err_t Err;
    ZigBee_Data_t Client={0};
    ZigBee_Data_Ack_t ServerAck={0}; ServerAck=ServerAck;
    uint16_t Server_ShortAddr=0;

    memcpy(Client.dev_mac, Zigbee_Property.Mac, sizeof(Zigbee_Property.Mac));

    ZigBee_Send_Data(Server_ShortAddr, &Client, sizeof(Client));

    // 等待服务端响应
    Err = ZigBee_WaitAck(TimeToWait);
    if( Err != TRUE ) { return Err; }

    if(ZigBee->Len != sizeof(ServerAck)+2) { return FALSE; }

    return TRUE;
}


